#include "loc.h"
#include "mem/scan.h"
#include "sign.h"
#include <format>

using namespace std;

string locate(uint32 pid) {
  string ret;
  HANDLE process = OpenProcess(PROCESS_ALL_ACCESS, false, pid);
  auto module_addrs = get_module_addr(pid);
  if (!module_addrs.has_value()) {
    dbgprintu8("codergege [%s][%03d] 游戏模块地址获取失败!\n", __FUNCTION__,
               __LINE__);
    return ret;
  }
  auto [start, end] = module_addrs.value();
  uint64 result{0};
  string tmp;

  ret += "#pragma once\n";
  ret += "#include \"basic/types.h\"\n\n";

  result = scan_base(process, start, end, SIGN_CORE_ARR_TMP_INDEX_BASE, 3, 2);
  tmp = format("constexpr uint64 RVA_CORE_ARR_TMP_INDEX_BASE = 0x{:X};\n",
               result);
  ret += tmp;

  result = scan_base(process, start, end, SIGN_PLAYER_ID_BASE, 0, 3);
  tmp = format("constexpr uint64 RVA_PLAYER_ID_BASE = 0x{:X};\n", result);
  ret += tmp;

  result = scan_base(process, start, end, SIGN_GET_OBJECT_INDEX_BASE, -0x1b, 3);
  tmp =
      format("constexpr uint64 RVA_GET_OBJECT_INDEX_BASE = 0x{:X};\n", result);
  ret += tmp;

  result = scan_base(process, start, end, SIGN_PLAYER_NAME_BASE, 2, 3);
  tmp = format("constexpr uint64 RVA_PLAYER_NAME_BASE = 0x{:X};\n", result);
  ret += tmp;

  result = scan_base(process, start, end, SIGN_CONTAINER_ID_BASE, 3, 3);
  tmp = format("constexpr uint64 RVA_CONTAINER_ID_BASE = 0x{:X};\n", result);
  ret += tmp;

  result = scan_base(process, start, end, SIGN_ITEM_PROP_BASE, 0xD, 3);
  tmp = format("constexpr uint64 RVA_ITEM_PROP_BASE = 0x{:X};\n", result);
  ret += tmp;

  result = scan_base(process, start, end, SIGN_ITEM_TYPE_ARR_BASE, 0xD, 3);
  tmp = format("constexpr uint64 RVA_ITEM_TYPE_ARR_BASE = 0x{:X};\n", result);
  ret += tmp;

  result = scan_base_in_call(process, start, end, SIGN_ITEM_TYPE_NAME_BASE,
                             0x31, 5, 3);
  tmp = format("constexpr uint64 RVA_ITEM_TYPE_NAME_BASE = 0x{:X};\n", result);
  ret += tmp;

  result = scan_call(process, start, end, SIGN_ITEM_SUBTYPE_CALL, -5);
  tmp = format("constexpr uint64 RVA_ITEM_SUBTYPE_CALL = 0x{:X};\n", result);
  ret += tmp;

  result = scan_base_in_call(process, start, end, SIGN_GET_TIME_BASE, -5, 0, 2);
  tmp = format("constexpr uint64 RVA_GET_TIME_BASE = 0x{:X};\n", result);
  ret += tmp;

  result = scan_base(process, start, end, SIGN_SPELL_NAME_BASE, 0xA, 3);
  tmp = format("constexpr uint64 RVA_SPELL_NAME_BASE = 0x{:X};\n", result);
  ret += tmp;

  result = scan_call(process, start, end, SIGN_SPELL_NAME_BASE, 0x11);
  tmp = format("constexpr uint64 RVA_SPELL_NAME_CALL = 0x{:X};\n", result);
  ret += tmp;

  result =
      scan_base_in_call(process, start, end, SING_SPELL_ID_BASE, -5, 0x29, 3);
  tmp = format("constexpr uint64 RVA_SPELL_ID_BASE = 0x{:X};\n", result);
  ret += tmp;

  result = scan_call(process, start, end, SIGN_SPELL_COOLDOWN_CALL, 0x1C);
  tmp = format("constexpr uint64 RVA_SPELL_COOLDOWN_CALL = 0x{:X};\n", result);
  ret += tmp;

  result = scan_raw_addr_rva(process, start, end, SIGN_COMMON_SEND_CALL, 0);
  tmp = format("constexpr uint64 RVA_COMMON_SEND_CALL = 0x{:X};\n", result);
  ret += tmp;

  result = scan_call(process, start, end, SIGN_CLICK_CALL, +0x8);
  tmp = format("constexpr uint64 RVA_CLICK_CALL = 0x{:X};\n", result);
  ret += tmp;

  result = scan_call(process, start, end, SIGN_MACRO, -0x35);
  tmp = format("constexpr uint64 RVA_MACRO_CALL = 0x{:X};\n", result);
  ret += tmp;

  result = scan_base(process, start, end, SIGN_MACRO, -0x3C, 3);
  tmp = format("constexpr uint64 RVA_MACRO_BASE = 0x{:X};\n", result);
  ret += tmp;

  result = scan_call(process, start, end, SIGN_SELECT_CALL, 0xB);
  tmp = format("constexpr uint64 RVA_SELECT_CALL = 0x{:X};\n", result);
  ret += tmp;

  result = scan_base_in_call(process, start, end, SIGN_SEND_MAIL_RCX_BASE,
                             -0x11, 2, 3);
  tmp = format("constexpr uint64 RVA_SEND_MAIL_RCX_BASE = 0x{:X};\n", result);
  ret += tmp;

  result =
      scan_base_in_call(process, start, end, SIGN_EQUIP_RCX_BASE, 0xD, 2, 3);
  tmp = format("constexpr uint64 RVA_EQUIP_RCX_BASE = 0x{:X};\n", result);
  ret += tmp;

  result = scan_base_in_call(process, start, end, SIGN_SELL_RCX_BASE, -5, 0, 3);
  tmp = format("constexpr uint64 RVA_SELL_RCX_BASE = 0x{:X};\n", result);
  ret += tmp;

  result =
      scan_base_in_call(process, start, end, SIGN_DESTROY_RCX_BASE, -5, 0, 3);
  tmp = format("constexpr uint64 RVA_DESTROY_RCX_BASE = 0x{:X};\n", result);
  ret += tmp;

  result = scan_base(process, start, end, SIGN_TAXI_NODE_ARR_BASE, 8, 3);
  tmp = format("constexpr uint64 RVA_TAXI_NODE_ARR_BASE = 0x{:X};\n", result);
  ret += tmp;

  result = scan_base(process, start, end, SIGN_TAXI_NODE_ARR_BASE, -7, 3);
  tmp =
      format("constexpr uint64 RVA_TAXI_NODE_ID_ARR_BASE = 0x{:X};\n", result);
  ret += tmp;

  result = scan_call(process, start, end, SIGN_TAXI_NODE_ARR_BASE, 0xF);
  tmp = format("constexpr uint64 RVA_TAXI_NODE_NAME_CALL = 0x{:X};\n", result);
  ret += tmp;

  result = scan_call(process, start, end, SIGN_TAKE_TAXI_CALL, 0xF);
  tmp = format("constexpr uint64 RVA_TAKE_TAXI_CALL = 0x{:X};\n", result);
  ret += tmp;

  return ret;
}
